
#define NORMAL 	1	//physical damage
#define FIRE	2	//fire damage
#define ICE		4	//ice damage
#define PIERCE	8	//pierce damage, do not calculate defense
#define ACID	16	//acid damage
#define LIGHT	32
#define DARK	64
#define ELEC	128
#define EARTH	256
#define WIND	512
#define WATER	1024

#define ICE WATER|EARTH
//define your own here, or just define more, it doesn't really matter

//single target
#define MISSILE 1
#define DRAG	2
#define INSTANT 4
#define CHAIN	8
#define DIRECT	16

//AOE
#define SCATTER	32
#define SQUARE	64
#define CONE	128
#define SHOCK	256

//flag for targetting group instead of enemies
#define GROUP	512

//flag for targetting single friendlies instead of enemies
#define FRIEND	1024

//for healing spells, make calcDamage return negative damage and set FRIEND or GROUP
skillobj
	icon='skills.dmi'
	parent_type=/skill
	density=1
	fireball/icon_state="fireball_obj"

	Bumped(atom/a)
		Bump(a)

	Bump(atom/a)
		if(a == caster) del src
		if(ismob(a))
			hit(a)
		del src

	New(loc, mob/own, dtimer)
		..(loc)
		caster = own
		if(dtimer)
			spawn(dtimer) del src

skill
	layer=MOB_LAYER+8
	density=1
	parent_type=/obj
	mouse_opacity=0
	var
		speed		= 3
		element
		attributes
		graphical 	= TRUE
		directions 	= list("NORTH","SOUTH","EAST","WEST")
		range		= 7
		repetitions	= 3

		mpcost		= 0

		mob/caster
		skillobj/rep

	New(loc, mob/own)
		..()
		caster = own

	LeftClick(mob/caller)
		//owner = caller
		cast(caller)


	MouseDrag()
		usr.client.mouse_pointer_icon = new /icon(icon, icon_state)

	MouseDrop(src_object,over_object,src_location,over_location,src_control,over_control,params)
		usr.client.mouse_pointer_icon = null
		if(istype(src_object, /obj/hud/selectable))
			var/obj/hud/selectable/s = src_object
			s.handle_skill(usr, new type(null, usr))

	proc
		getTarget(mob/ref)
			for(var/mob/m in oview(range, ref))
				if(attributes & FRIEND)
					if(m.client)
						return m
					continue
				return m

		hit(mob/a)
			dealDamage(a)
			if(attributes & SHOCK & CHAIN)
				new/shockwave(a, icon)
				//purely graphical
				//mobs need a proc that damages them
				//and that needs to be fed into the shockwave proc
				//see lib.dm for details

			if(attributes & CHAIN)
				if(repetitions-->0)
					//var/mob/target = getTarget(a)
					//move to the target
					//while(moving) (make this move)
					//add the below to the while loop
					if(attributes & DRAG)
						if(graphical)
							new rep(loc)
					//it should hit when it bumps it
				//	hit(target)

		cast(mob/owner, mob/target, recalled)

			if(!owner.mp > mpcost)
				owner << "You do not have enough energy to cast this spell!"
				return

	//		if(attributes & GROUP)
				/*
				this is when the group system gets implemented
				talk to me about this sometime
				for(var/mob/m in group.getMembers())
					cast(m, 1)
				*/
			if(!target)
				target = getTarget(owner)
				if(!target)
					owner << "No target in range."
					return

			if(attributes & MISSILE)
				var/skillobj/s = new rep(loc, owner)
				spawn while(s)
					if(attributes & DRAG)
						if(graphical)
							new rep(loc)
					step_towards(s, target)
					sleep(speed)
					//make the missile drop objects on it's path

			else if(attributes & INSTANT)
				//hit the target instantly
				hit(target)
				if(rep)
					var/obj/o = new rep(null, null, 5)
					var/icon/i = new(o.icon, o.icon_state)
					target.overlays += i
					spawn(10)
						if(target) target.overlays -= i

			else if(attributes & DIRECT)
				//shoot out objects in each direction
				for(var/o in directions)
					var/skillobj/s = new rep(loc, owner)
					//we spawn so they all go at once
					spawn for(var/x=1 to range)
						step(s, text2num(o))
						//drop an object to show I've been here
						if(attributes & DRAG)
							if(graphical)
								new rep(s.loc, owner, 10)

			else if(attributes & SQUARE)
				for(var/turf/t in oview(range,owner))
					if(graphical && rep)
						new rep(t)
				for(var/mob/m in oview(range, owner))
					//friendly spell, friendly target
					if(m.client && attributes & FRIEND)
						hit(m)
					//not friendly spell, not friendly target
					//coincidence? I think not!
					else if(!(attributes & FRIEND) && !m.client)
						hit(m)

			else if(attributes & CONE)
				for(var/turf/t in cone(owner, owner.dir, oview(owner, range)))
					if(graphical && rep)
						new rep(t)
				for(var/mob/m in cone(owner, owner.dir, oview(owner, range)))
					hit(m)

			else if(attributes & SHOCK)
				new/shockwave(owner, icon)

			owner.mp -= mpcost

			if(isplayer(owner))
				var/mob/player/p = owner
				p.update_bars()

		calcDamage(mob/caster, mob/target)
			if(!target) return caster.int

			if(attributes & FRIEND)
				return caster.wis

			//calculate damage based on owner stats
			return caster.int - target.wis > 0 ? caster.int - target.wis : 0

		dealDamage(mob/caster, mob/target)

			var/damage = 0
			//deal damage based on calc'd damage, and monster stats
			//if(element & NORMAL){}
				//calculation for defense-damage
			//if(element & FIRE)
			//	if(m.resistances["fire"]){}
					//calculate my damage minus their resistance
			if(element & PIERCE)
				damage = calcDamage(caster)

			else
				damage = calcDamage(caster, target)

			target.losehealth(damage, caster)